package com.eternal.details;

import android.annotation.SuppressLint;
import android.content.Intent;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import androidx.appcompat.widget.AppCompatImageView;

import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;

import com.eternal.base.concat.DeviceInfo;
import com.eternal.base.concat.DeviceName;
import com.eternal.base.global.BluetoothKey;
import com.eternal.base.utils.CustomToastUtils;
import com.eternal.framework.utils.KLog;
import com.eternal.framework.utils.RxUtils;
import com.google.android.material.tabs.TabLayout;

import com.alibaba.android.arouter.facade.Postcard;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.facade.callback.NavCallback;
import com.alibaba.android.arouter.launcher.ARouter;
import com.eternal.base.IConnectAction;
import com.eternal.base.LogService;
import com.eternal.base.concat.BluetoothEvent;
import com.eternal.base.data.RepositoryInjection;
import com.eternal.base.global.ActivityEvent;
import com.eternal.base.global.ProgressEvent;
import com.eternal.base.protocol.ProtocolTransformer;
import com.eternal.base.router.RouterActivityPath;
import com.eternal.base.router.RouterFragmentPath;
import com.eternal.framework.bus.RxBus;
import com.eternal.framework.utils.Utils;
import com.eternal.widget.guqiang.ProgressToolbar;

import org.reactivestreams.Publisher;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Completable;
import io.reactivex.CompletableEmitter;
import io.reactivex.CompletableOnSubscribe;
import io.reactivex.CompletableSource;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import q.rorbin.badgeview.Badge;
import q.rorbin.badgeview.QBadgeView;

import static com.eternal.framework.utils.Utils.getContext;
import static com.eternal.framework.utils.Utils.getString;

/**
 * 控制页
 *
 * @author Administrator
 */
@Route(path = RouterActivityPath.Detail.PAGE_DETAIL)
public class DetailsActivity extends AppCompatActivity {
    private String mac, timeStr;
    private byte port;
    private TabLayout layout;
    private ProgressToolbar toolbar;
    private String[] titles;
    private List<Fragment> fragments;
    private Disposable timeEvent, connectEvent, progressEvent;
    private Badge logBadge;
    private Disposable logNum, timeDispose, nameRefresh;
    private byte deviceType;
    private Fragment nowFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_details);
        //初始化顺序不可变
        initView();
        initFragment();
        if (ActivityEvent.ACTION_LOG.equals(getIntent().getAction())) {
            layout.getTabAt(3).select();
        } else {
            nowFragment = fragments.get(0);
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.show(nowFragment);
            transaction.commit();
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (ActivityEvent.ACTION_LOG.equals(intent.getAction())) {
            layout.getTabAt(3).select();
        }
    }

    @Override
    protected void onDestroy() {
        toolbar.cancelProgress();
        unregisterEvent();
        if (nameRefresh != null) {
            nameRefresh.dispose();
            nameRefresh = null;
        }
        super.onDestroy();
    }

    private void registerEvent() {
        if (timeEvent == null || timeEvent.isDisposed()) {
            timeEvent = RxBus.getDefault()
                    .toObservable(Long.class)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long time) throws Exception {
                            toolbar.setTime(Utils.getString(R.string.tip_connect,
                                    ProtocolTransformer.getTime(time)));
                        }
                    });
        }

        //接收控制页设备状态变更消息，显示加载进度条
        if (progressEvent == null || progressEvent.isDisposed()) {
            progressEvent = RxBus.getDefault()
                    .toObservable(ProgressEvent.class)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<ProgressEvent>() {
                        @Override
                        public void accept(ProgressEvent event) {
                            switch (event.Statue) {
                                case ProgressEvent.START:
                                    toolbar.startProgress();
                                    break;
                                case ProgressEvent.END:
                                    toolbar.endProgress(event.callback);
                                    break;
                                case ProgressEvent.INIT:
                                    toolbar.initProgress(event.percent, 3000);
                                    break;
                                default:
                                    toolbar.setAnimatorProgress(event.percent);
                            }
                        }
                    });
        }
    }

    private void unregisterEvent() {
        if (timeEvent != null) {
            timeEvent.dispose();
            timeEvent = null;
        }
        if (connectEvent != null) {
            connectEvent.dispose();
            connectEvent = null;
        }
        if (progressEvent != null) {
            progressEvent.dispose();
            toolbar.cancelProgress();
            progressEvent = null;
        }
    }

    private void initView() {
        mac = getIntent().getStringExtra(ActivityEvent.DEVICE_MAC);
        port = getIntent().getByteExtra(ActivityEvent.DEVICE_PORT, (byte) 0x0);
        timeStr = getIntent().getStringExtra(ActivityEvent.DEVICE_TIME);
        deviceType = getIntent().getByteExtra(ActivityEvent.DEVICE_TYPE, (byte) 1);

        titles = getResources().getStringArray(R.array.details_title);
        toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle(titles[0]);
        toolbar.getBack().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBack(v);
            }
        });
        toolbar.getNext().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onNext(v);
            }
        });
        layout = findViewById(R.id.tb_bottom);
        TabLayout.Tab tab = layout.newTab();
        View view = LayoutInflater.from(this).inflate(R.layout.details_item_log, tab.parent, false);
        final AppCompatImageView imageView = view.findViewById(R.id.tabicon);
        logBadge = new QBadgeView(this).bindTarget(imageView)
                .setExactMode(true)     //精准模式，超过99显示具体数字
                .setBadgeGravity(Gravity.TOP | Gravity.END);
        tab.setCustomView(view);
        imageView.setSelected(false);
        int i = 0;
        layout.addTab(layout.newTab().setIcon(R.drawable.control_icon_selector), i++);
        if (deviceType == BluetoothKey.DEVICE_TYPE_A || deviceType == BluetoothKey.DEVICE_TYPE_B || deviceType == BluetoothKey.DEVICE_TYPE_E) {
            layout.addTab(layout.newTab().setIcon(R.drawable.advance_icon_selector), i++);
        }
        layout.addTab(layout.newTab().setIcon(R.drawable.datapage_icon_selector), i++);
        layout.addTab(tab, i);

        layout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                replaceFragment(tab.getPosition());
                if (tab.getPosition() == layout.getTabCount() - 1) {
                    imageView.setSelected(true);
                } else {
                    imageView.setSelected(false);
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

        refreshLogNum();
        refreshName();
        if (RepositoryInjection.providerDeviceRepository().isConnect(mac)) {
            toolbar.setTimeColor(ContextCompat.getColor(DetailsActivity.this, android.R.color.white));
            toolbar.setTime(Utils.getString(R.string.tip_connect,
                    ProtocolTransformer.getTime(System.currentTimeMillis())));
            registerEvent();
        } else {
            toolbar.setTimeColor(ContextCompat.getColor(DetailsActivity.this, R.color.color_FF2D55));
            toolbar.setTime(timeStr);
        }
        registerConnect();
    }

    private void registerConnect() {
        connectEvent = RxBus.getDefault()
                .toObservable(BluetoothEvent.class)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<BluetoothEvent>() {
                    @Override
                    public void accept(BluetoothEvent event) throws Exception {
                        if (!mac.equals(event.obj)) {
                            return;
                        }
                        if (event.what == BluetoothEvent.DISCONNECT) {                              //蓝牙连接断开
                            Completable.create(new CompletableOnSubscribe() {
                                @Override
                                public void subscribe(CompletableEmitter emitter) throws Exception {
                                    timeStr = Utils.getString(R.string.tip_last,
                                            ProtocolTransformer.getTime(System.currentTimeMillis()));
                                    toolbar.setTime(timeStr);
                                    toolbar.setTimeColor(ContextCompat.getColor(DetailsActivity.this, R.color.color_FF2D55));
//                                    onBackPressed();
                                }
                            }).subscribeOn(AndroidSchedulers.mainThread()).subscribe();

                            if (timeEvent != null) {
                                timeEvent.dispose();
                                timeEvent = null;
                            }
                            if (progressEvent != null) {
                                progressEvent.dispose();
                                progressEvent = null;
                            }
                            if (nowFragment instanceof IConnectAction) {
                                ((IConnectAction) nowFragment).disconnected();
                            }
                        } else if (event.what == BluetoothEvent.REFRESH_BADGE) {                    //设置log角标数量
                            if (logBadge.getBadgeNumber() != event.i1) {
                                logBadge.setBadgeNumber(event.i1);
                            }
                        } else if (event.what == BluetoothEvent.CONNECT) {
                            timeStr = null;
                            toolbar.setTimeColor(ContextCompat.getColor(DetailsActivity.this, android.R.color.white));
                            toolbar.setTime(Utils.getString(R.string.tip_connect,
                                    ProtocolTransformer.getTime(System.currentTimeMillis())));
                            registerEvent();
                            refreshLogNum();
                            if (nowFragment instanceof IConnectAction) {
                                ((IConnectAction) nowFragment).connected();
                            }
                        }
                    }
                });
    }

    @SuppressLint("CheckResult")
    private void refreshName() {
        if (nameRefresh == null || nameRefresh.isDisposed()) {
            nameRefresh = RepositoryInjection.providerDeviceRepository()
                    .getDeviceName(mac, port)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<DeviceName>() {
                        @Override
                        public void accept(DeviceName deviceName) {
                            if (deviceName != null) {
                                toolbar.setSubtitle(deviceName.name);
                            }
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) {
                            KLog.e(throwable);
                        }
                    });
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (RepositoryInjection.providerDeviceRepository().isConnect(mac)) {
            toolbar.setTime(Utils.getString(R.string.tip_connect,
                    ProtocolTransformer.getTime(System.currentTimeMillis())));
        }
        refreshLogNum();
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopRefreshLog();
    }

    private void stopRefreshLog() {
        if (logNum != null) {
            logNum.dispose();
            logNum = null;
        }
        if (timeDispose != null) {
            timeDispose.dispose();
            timeDispose = null;
        }
    }

    /**
     * 更新日志信息和日志角标数量
     */
    private void refreshLogNum() {
        if (logNum == null || logNum.isDisposed()) {
            logNum = RepositoryInjection.providerLogRepository().getNewLogNum(mac, port)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Integer>() {
                        @Override
                        public void accept(Integer integer) {
                            logBadge.setBadgeNumber(integer);
                        }
                    });
        }

        if (timeDispose == null || timeDispose.isDisposed()) {
            timeDispose = RxBus.getDefault().toObservable(Long.class)
                    .flatMapCompletable(new Function<Long, CompletableSource>() {
                        @Override
                        public CompletableSource apply(Long aLong) throws Exception {
                            if (aLong % 2 == 0) {
                                return LogService.getInstance().addRefresh(mac, port).subscribeOn(Schedulers.io());
                            } else {
                                return Completable.complete();
                            }
                        }
                    }).subscribeOn(Schedulers.io()).subscribe();
        }
    }

    private void initFragment() {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        fragments = new ArrayList<>(4);
        ARouter router = ARouter.getInstance();
        Fragment fragment;
        if (deviceType == BluetoothKey.DEVICE_TYPE_A || deviceType == BluetoothKey.DEVICE_TYPE_B || deviceType == BluetoothKey.DEVICE_TYPE_E) {
            fragment = (Fragment) router.build(RouterFragmentPath.Control.PAGE_CONTROL)
                    .withString(ActivityEvent.DEVICE_MAC, mac)
                    .withByte(ActivityEvent.DEVICE_PORT, port)
                    .withBoolean(ActivityEvent.DEVICE_CONNECTED, TextUtils.isEmpty(timeStr))
                    .navigation(this);
            fragments.add(fragment);
            transaction.add(R.id.frame_layout, fragment, "0");
            nowFragment = fragment;

            fragment = (Fragment) router.build(RouterFragmentPath.Advance.PAGE_ADVANCE)
                    .withString(ActivityEvent.DEVICE_MAC, mac)
                    .withByte(ActivityEvent.DEVICE_PORT, port)
                    .withBoolean(ActivityEvent.DEVICE_CONNECTED, TextUtils.isEmpty(timeStr))
                    .navigation(this);
            fragments.add(fragment);
            transaction.add(R.id.frame_layout, fragment, "1").hide(fragment);
        } else {
            fragment = (Fragment) router.build(RouterFragmentPath.Control.PAGE_CONTROL_C)
                    .withString(ActivityEvent.DEVICE_MAC, mac)
                    .withByte(ActivityEvent.DEVICE_PORT, port)
                    .withBoolean(ActivityEvent.DEVICE_CONNECTED, TextUtils.isEmpty(timeStr))
                    .navigation(this);
            fragments.add(fragment);
            transaction.add(R.id.frame_layout, fragment, "1");
            nowFragment = fragment;
        }
        fragment = (Fragment) router.build(RouterFragmentPath.Data.PAGE_DATA)
                .withString(ActivityEvent.DEVICE_MAC, mac)
                .withByte(ActivityEvent.DEVICE_PORT, port)
                .withByte(ActivityEvent.DEVICE_TYPE, deviceType)
                .withBoolean(ActivityEvent.DEVICE_CONNECTED, TextUtils.isEmpty(timeStr))
                .navigation(this);
        fragments.add(fragment);
        transaction.add(R.id.frame_layout, fragment, "2").hide(fragment);

        if (deviceType == BluetoothKey.DEVICE_TYPE_A || deviceType == BluetoothKey.DEVICE_TYPE_B || deviceType == BluetoothKey.DEVICE_TYPE_E) {
            fragment = (Fragment) router.build(RouterFragmentPath.Log.PAGE_LOG)
                    .withString(ActivityEvent.DEVICE_MAC, mac)
                    .withByte(ActivityEvent.DEVICE_PORT, port)
                    .withBoolean(ActivityEvent.DEVICE_CONNECTED, TextUtils.isEmpty(timeStr))
                    .navigation(this);
        } else {
            fragment = (Fragment) router.build(RouterFragmentPath.Log.PAGE_LOG_C)
                    .withString(ActivityEvent.DEVICE_MAC, mac)
                    .withByte(ActivityEvent.DEVICE_PORT, port)
                    .withBoolean(ActivityEvent.DEVICE_CONNECTED, TextUtils.isEmpty(timeStr))
                    .navigation(this);
        }
        fragments.add(fragment);
        transaction.add(R.id.frame_layout, fragment, "3").hide(fragment);
        transaction.commit();
    }

    private void replaceFragment(int index) {
        if (index < fragments.size()) {
            toolbar.cancelProgress();
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.hide(nowFragment);
            nowFragment = fragments.get(index);
            transaction.show(nowFragment);
            transaction.commit();
        }
        if (deviceType == BluetoothKey.DEVICE_TYPE_C
                || deviceType == BluetoothKey.DEVICE_TYPE_C1
                || deviceType == BluetoothKey.DEVICE_TYPE_C2) {
            if (index > 0) {
                ++index;
            }
        }
        toolbar.setTitle(titles[index]);
    }

    @Override
    public void onBackPressed() {
        onBack(null);
    }

    public void onBack(View view) {
        Postcard postcard = ARouter.getInstance().build(RouterActivityPath.Main.PAGE_MAIN)
                .withTransition(R.anim.left_in, R.anim.right_out);
        postcard.navigation(this, new NavCallback() {
            @Override
            public void onArrival(Postcard postcard) {
                finish();
            }
        });
    }

    public void onNext(View view) {
        ARouter.getInstance().build(RouterActivityPath.Setting.PAGE_SETTING)
                .withString(ActivityEvent.DEVICE_MAC, mac)
                .withByte(ActivityEvent.DEVICE_PORT, port)
                .withString(ActivityEvent.DEVICE_TIME, timeStr)
                .withByte(ActivityEvent.DEVICE_TYPE, deviceType)
                .withTransition(R.anim.right_in, R.anim.left_out)
                .navigation(this);
    }
}